#! /usr/bin/env node

const path = require("path");
const fs = require("fs");
const { exec } = require("child_process");
const fse = require("fs-extra");
const request = require("request");
const cheerio = require("cheerio");
const topics = require("./topics");

const imageFolder = path.resolve(path.join(__dirname, "images"));
const site = "https://www.pexels.com/";

// String -> Promise<String>
// get 方法获取网页 html
async function get(url) {
  return new Promise((resolve, reject) =>
    request(url, (error, _, body) => (error ? reject(error) : resolve(body)))
  );
}

// Number -> Number
// 获取随机数
function getRandomNumber(max) {
  if (max <= 0) return max;
  const floor = n => (n >= 1 ? n : floor(n * 10));
  return Math.round(floor(Math.random()));
}

// String -> Number
// 获取随机页码
function getRandomPageNum(html) {
  const $ = cheerio.load(html);

  const array = $('.pagination a:not([class="next_page"])')
    .map((_, a) => parseInt($(a).text(), 10))
    .filter(n => !Number.isNaN(n));

  return getRandomNumber(Math.max(...Array.from(array)));
}

// String -> String
// 获取页面中的随机图片链接
function getRandomImageUrl(html) {
  const $ = cheerio.load(html);
  const array = $(".photos .photo-item a[download]").map((_, a) =>
    $(a).attr("href")
  );

  return array[getRandomNumber(array.length - 1)];
}

// String -> String
// 解析图片地址中的图片名称
function getImageExtName(imageUrl) {
  const [urlPath] = imageUrl.split("?");
  const name = urlPath.split("/").pop();
  return name.split(".").pop();
}

// Undefined -> Undefined
// 清空图片文件夹所有图片
function prepareFolder() {
  fse.emptyDirSync(imageFolder);
  fse.ensureDirSync(imageFolder);
}

// String -> Undefined
// 设置图片为桌面背景
function setDesktopWallpaper(absolutePath) {
  const cm =
    `osascript -e 'tell application "Finder" ` +
    `to set desktop picture to POSIX file "${absolutePath}"'`;
  exec(cm);
}

// String String -> Undefined
// 通知
function notify(message, title = "壁纸") {
  const cm =
    `osascript -e 'display notification ` +
    `"${message}" with title "${title}"'`;
  exec(cm);
}

// Undefined -> Undefined
// 切换成功提醒
function successNotify() {
  notify("切换壁纸");
}

// Undefined -> Undefiend
// 切换壁纸失败
function failNotify(message) {
  notify(`切换壁纸失败，失败原因：${message}`);
}

// Array<String> -> Promise<Undefined>
async function main(topics) {
  // 清空图片文件夹
  prepareFolder();

  const topic = topics[getRandomNumber(topics.length - 1)];

  // 搜索页，首页页面
  const searchMainHtml = await get(`${site}/search/${topic}`);

  // 搜索页，随机页面
  const randamPageNum = getRandomPageNum(searchMainHtml);
  const searchRandomHtml = await get(
    `${site}/search/${topic}/?page=${randamPageNum}`
  );

  // 页面随机图片链接
  const imageUrl = getRandomImageUrl(searchRandomHtml);

  const filename = `${Date.now()}.${getImageExtName(imageUrl)}`;
  const filePath = path.join(imageFolder, filename);

  const fileStream = fs.createWriteStream(filePath);

  fileStream.on("close", () => {
    setDesktopWallpaper(filePath);
    successNotify();
  });

  // 下载图片保存
  request(imageUrl).pipe(fileStream);
}

main(topics).catch(e => failNotify(e.message));
